home *** CD-ROM | disk | FTP | other *** search
- import aetools
- import Standard_Suite
- import Required_Suite
- import WWW_Suite
- import regex
- import W
- import macfs
- import os
- import MacPrefs
- import MacOS
- import string
-
- if hasattr(WWW_Suite, "WWW_Suite"):
- WWW = WWW_Suite.WWW_Suite
- else:
- WWW = WWW_Suite.WorldWideWeb_suite_2c__as_defined_in_Spyglass_spec_2e_
-
- class WebBrowser(aetools.TalkTo,
- Standard_Suite.Standard_Suite,
- WWW):
-
- def openfile(self, path, activate = 1):
- if activate:
- self.activate()
- self.OpenURL("file:///" + string.join(string.split(path,':'), '/'))
-
- app = W.getapplication()
-
- #SIGNATURE='MSIE' # MS Explorer
- SIGNATURE='MOSS' # Netscape
-
- _titlepat = regex.compile('<title>\([^<]*\)</title>')
-
- def sucktitle(path):
- f = open(path)
- text = f.read(1024) # assume the title is in the first 1024 bytes
- f.close()
- lowertext = string.lower(text)
- if _titlepat.search(lowertext) > 0:
- a, b = _titlepat.regs[1]
- return text[a:b]
- return path
-
- def verifydocpath(docpath):
- try:
- tut = os.path.join(docpath, "tut")
- lib = os.path.join(docpath, "lib")
- ref = os.path.join(docpath, "ref")
- for path in [tut, lib, ref]:
- if not os.path.exists(path):
- return 0
- except:
- return 0
- return 1
-
-
- class TwoLineList(W.List):
-
- LDEF_ID = 468
-
- def createlist(self):
- import List
- self._calcbounds()
- self.SetPort()
- rect = self._bounds
- rect = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
- self._list = List.LNew(rect, (0, 0, 1, 0), (0, 28), self.LDEF_ID, self._parentwindow.wid,
- 0, 1, 0, 1)
- self.set(self.items)
-
-
- _resultscounter = 1
-
- class Results:
-
- def __init__(self, hits):
- global _resultscounter
- hits = map(lambda (path, hits): (sucktitle(path), path, hits), hits)
- hits.sort()
- self.hits = hits
- nicehits = map(
- lambda (title, path, hits):
- title + '\r' + string.join(
- map(lambda (c, p): "%s (%d)" % (p, c), hits), ', '), hits)
- nicehits.sort()
- self.w = W.Window((440, 300), "Search results %d" % _resultscounter, minsize = (200, 100))
- self.w.results = TwoLineList((-1, -1, 1, -14), nicehits, self.listhit)
- self.w.open()
- self.w.bind('return', self.listhit)
- self.w.bind('enter', self.listhit)
- _resultscounter = _resultscounter + 1
- self.browser = None
-
- def listhit(self, isdbl = 1):
- if isdbl:
- for i in self.w.results.getselection():
- if self.browser is None:
- self.browser = WebBrowser(SIGNATURE, start = 1)
- self.browser.openfile(self.hits[i][1])
-
- class Status:
-
- def __init__(self):
- self.w = W.Dialog((440, 64), "Searching…")
- self.w.searching = W.TextBox((4, 4, -4, 16), "DevDev:PyPyDoc 1.5.1:ext:parseTupleAndKeywords.html")
- self.w.hits = W.TextBox((4, 24, -4, 16), "Hits: 0")
- self.w.canceltip = W.TextBox((4, 44, -4, 16), "Type cmd-period (.) to cancel.")
- self.w.open()
-
- def set(self, path, hits):
- self.w.searching.set(path)
- self.w.hits.set('Hits: ' + `hits`)
- app.breathe()
-
- def close(self):
- self.w.close()
-
-
- def match(text, patterns, all):
- hits = []
- hitsappend = hits.append
- stringcount = string.count
- for pat in patterns:
- c = stringcount(text, pat)
- if c > 0:
- hitsappend((c, pat))
- elif all:
- hits[:] = []
- break
- hits.sort()
- hits.reverse()
- return hits
-
- def dosearch(docpath, searchstring, settings):
- (docpath, kind, case, word, tut, lib, ref, ext, api) = settings
- books = [(tut, 'tut'), (lib, 'lib'), (ref, 'ref'), (ext, 'ext'), (api, 'api')]
- if not case:
- searchstring = string.lower(searchstring)
-
- if kind == 1:
- patterns = string.split(searchstring)
- all = 1
- elif kind == 2:
- patterns = string.split(searchstring)
- all = 0
- else:
- patterns = [searchstring]
- all = 0 # not relevant
-
- ospathjoin = os.path.join
- stringlower = string.lower
- status = Status()
- statusset = status.set
- _match = match
- _open = open
- hits = {}
- try:
- MacOS.EnableAppswitch(0)
- try:
- for do, name in books:
- if not do:
- continue
- bookpath = ospathjoin(docpath, name)
- if not os.path.exists(bookpath):
- continue
- files = os.listdir(bookpath)
- for file in files:
- fullpath = ospathjoin(bookpath, file)
- if fullpath[-5:] <> '.html':
- continue
- statusset(fullpath, len(hits))
- f = _open(fullpath)
- text = f.read()
- if not case:
- text = stringlower(text)
- f.close()
- filehits = _match(text, patterns, all)
- if filehits:
- hits[fullpath] = filehits
- finally:
- MacOS.EnableAppswitch(-1)
- status.close()
- except KeyboardInterrupt:
- pass
- hits = hits.items()
- hits.sort()
- return hits
-
-
- class PyDocSearch:
-
- def __init__(self):
- prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
- try:
- (docpath, kind, case, word, tut, lib, ref, ext, api) = prefs.docsearchengine
- except:
- (docpath, kind, case, word, tut, lib, ref, ext, api) = prefs.docsearchengine = \
- ("", 0, 0, 0, 1, 1, 0, 0, 0)
-
- if docpath and not verifydocpath(docpath):
- docpath = ""
-
- self.w = W.Window((400, 200), "Search the Python Documentation")
- self.w.searchtext = W.EditText((10, 10, -100, 20), callback = self.checkbuttons)
- self.w.searchbutton = W.Button((-90, 12, 80, 16), "Search", self.search)
- buttons = []
-
- gutter = 10
- width = 130
- bookstart = width + 2 * gutter
- self.w.phraseradio = W.RadioButton((10, 38, width, 16), "As a phrase", buttons)
- self.w.allwordsradio = W.RadioButton((10, 58, width, 16), "All words", buttons)
- self.w.anywordsradio = W.RadioButton((10, 78, width, 16), "Any word", buttons)
- self.w.casesens = W.CheckBox((10, 98, width, 16), "Case sensitive")
- self.w.wholewords = W.CheckBox((10, 118, width, 16), "Whole words")
- self.w.tutorial = W.CheckBox((bookstart, 38, -10, 16), "Tutorial")
- self.w.library = W.CheckBox((bookstart, 58, -10, 16), "Library reference")
- self.w.langueref = W.CheckBox((bookstart, 78, -10, 16), "Lanuage reference manual")
- self.w.extending = W.CheckBox((bookstart, 98, -10, 16), "Extending & embedding")
- self.w.api = W.CheckBox((bookstart, 118, -10, 16), "C/C++ API")
-
- self.w.setdocfolderbutton = W.Button((10, -30, 80, 16), "Set doc folder", self.setdocpath)
-
- if docpath:
- self.w.setdefaultbutton(self.w.searchbutton)
- else:
- self.w.setdefaultbutton(self.w.setdocfolderbutton)
-
- self.docpath = docpath
- if not docpath:
- docpath = "(please select the Python html documentation folder)"
- self.w.docfolder = W.TextBox((100, -28, -10, 16), docpath)
-
- [self.w.phraseradio, self.w.allwordsradio, self.w.anywordsradio][kind].set(1)
-
- self.w.casesens.set(case)
- self.w.wholewords.set(word)
- self.w.tutorial.set(tut)
- self.w.library.set(lib)
- self.w.langueref.set(ref)
- self.w.extending.set(ext)
- self.w.api.set(api)
-
- self.w.open()
- self.w.wholewords.enable(0)
- self.w.bind('<close>', self.close)
- self.w.searchbutton.enable(0)
-
- def search(self):
- hits = dosearch(self.docpath, self.w.searchtext.get(), self.getsettings())
- if hits:
- Results(hits)
- elif hasattr(MacOS, 'SysBeep'):
- MacOS.SysBeep(0)
- #import PyBrowser
- #PyBrowser.Browser(hits)
-
- def setdocpath(self):
- fss, ok = macfs.GetDirectory()
- if ok:
- docpath = fss.as_pathname()
- if not verifydocpath(docpath):
- W.Message("This does not seem to be a Python documentation folder...")
- else:
- self.docpath = docpath
- self.w.docfolder.set(docpath)
- self.w.setdefaultbutton(self.w.searchbutton)
-
- def close(self):
- prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
- prefs.docsearchengine = self.getsettings()
-
- def getsettings(self):
- radiobuttons = [self.w.phraseradio, self.w.allwordsradio, self.w.anywordsradio]
- for i in range(3):
- if radiobuttons[i].get():
- kind = i
- break
- docpath = self.docpath
- case = self.w.casesens.get()
- word = self.w.wholewords.get()
- tut = self.w.tutorial.get()
- lib = self.w.library.get()
- ref = self.w.langueref.get()
- ext = self.w.extending.get()
- api = self.w.api.get()
- return (docpath, kind, case, word, tut, lib, ref, ext, api)
-
- def checkbuttons(self):
- self.w.searchbutton.enable(not not self.w.searchtext.get())
-